﻿/*
	作者:武汉命运科技有限公司
	邮箱:1085617561@qq.com
	描述:新颖网络Word图片粘贴控件
	此文件实现上传后自动关闭上传窗口的功能
*/
KE.lang['imagepaster'] = "粘贴图片或自动上传Word图片";
KE.plugin['imagepaster'] = {
	click: function(id)
	{
		pasterMgr.Paste();
	}
};
//plugin-excel
KE.lang['excelpaster'] = "粘贴Excel";
KE.plugin['excelpaster'] = {
	click: function(id)
	{
		pasterMgr.PasteExcel();
	}
};

//全局对象
var WordPasterManagerInstance = null; //全局实例
//系统错误
var WordPasterError = {
	"0": "连接服务器错误"
	, "1": "发送数据错误"
	, "2": "接收数据错误"
	, "3": "本地文件不存在"
	, "4": "不能读取本地文件"
	, "5": "公司未授权"
	, "6": "未设置IP"
	, "7": "域名未授权"
};
/*
	上传对象管理器
	关联HTML元素：
		文件上传列表：FilePostLister
		文件上传列表项模板：UploaderTemplate
		文件上传列表分隔线：FilePostLine
*/
function WordPasterManager(mgr)
{
	WordPasterManagerInstance = this;//全局实例
	this.Manager = mgr;//粘贴管理器
	this.ActiveX = mgr.ActiveX;
	this.Config = mgr.Config;
	this.Fields = mgr.Fields;
	this.WordParser = mgr.WordParser;
	this.WordParser.Object = this;
	this.WordParser.AddWordImg = WordParser_AddImage;
	this.OpenDialog = mgr.OpenUploadFileDialog;
	this.CloseDialog = mgr.CloseUploadFileDialog;
	
	this.EditorContent = ""; //编辑器内容。当图片上传完后需要更新此变量值
	this.Editor = null; //编辑器
	this.CurrentUploader = null; //当前上传项。
	this.UploaderListDiv = document.getElementById("FilePostLister"); //上传列表层
	this.UploaderTemplateDiv = document.getElementById("UploaderTemplate"); //上传项信息层模板
	this.UploaderSplitLine = document.getElementById("FilePostLine"); //上传列表分割线
	this.UploaderList = new Object(); //上传项列表
	//已上传图片列表
	//模型：LocalUrl:ServerUrl
	this.UploadCompleteImage = new Array();
	this.UploaderListCount = 0; //上传项总数
	this.UnUploaderIdList = new Array(); //未上传项ID列表

	//photo regex
	this.ImgRegx = /<img width=\"\d+\" height=\"\d+\" alt=\"\S*\" src=\"file:\/\/\/(\S+)\"\ \/>/gi;
	this.ImgRegx2 = /<img src=\"file:\/\/\/(\S+)\" width=\d+ height=\d+>/gi;
	this.ShapeStyleRegexs = {
		wh: /(?:width: )(\S+)pt; (?:height: )(\S+)pt/i
	, w: /(?:width: )(\S+)pt;/i
	};
	this.StyleSrcRegx = /style=\"(.*)\"(?:.*)src=\"file:\/\/\/(\S+)\"/;
	this.imgSrcRegex = /(?:src=\"file:\/\/\/)(\S+)\"/;
	this.ImgRegex = {
		word: /<v:imagedata o:title=\"\S*\" src=\"file:\/\/\/(\S+)\"><\/v:imagedata>/gi
		, word2: /src=\"file:\/\/\/(\S+)\"><\/v:imagedata>/gi
		, app: /<v:imagedata src=\"file:\/\/\/(\S+)\" o:href=\"(\S+)\"><\/v:imagedata>/gi
		, web: /<v:imagedata o:href=\"(\S+)\" src=\"file:\/\/\/(\S+)\"><\/v:imagedata>/gi
		, loc: /<v:imagedata src=\"file:\/\/\/(\S+)\" o:title=\"\S*\"><\/v:imagedata>/gi
		, wps: /<img width=\"\d+\" height=\"\d+\" alt=\"\S*\" src=\"file:\/\/\/(\S+)\" \/>/gi
		, wps2: /<img src=\"file:\/\/\/(\S+)\" width=\d+ height=\d+>/gi
	};

	//检查是否存在本地相同图片
	this.CompleteExist = function(localPath)
	{
		for (var i = 0, l = this.UploadCompleteImage.length ; i < l ; ++i)
		{
			if (this.UploadCompleteImage[i].localPath == localPath)
			{
				return true;
			}
		}
		return false;
	};

	//添加到已完成列表
	this.CompleteAdd = function(localPathStr, serverPathStr)
	{
		this.UploadCompleteImage.push({ localPath: localPathStr, serverPath: serverPathStr });
	};

	//清空已完成列表，关闭图片上传对话框时调用
	this.CompleteClear = function()
	{
		this.UploadCompleteImage.length = 0;
	};

	//获取已完成的图片地址
	this.CompleteGet = function(localPath)
	{
		for (var i = 0, l = this.UploadCompleteImage.length; i < l; ++i)
		{
			if (this.UploadCompleteImage[i].localPath == localPath)
			{
				return this.UploadCompleteImage[i].serverPath;
			}
		}
		return "";
	};
	
	//粘贴Word
	this.PasteWord = function()
	{
		this.EditorContent = this.WordParser.GetWord();
		//有图片
		if (this.WordParser.GetImages())
		{
			this.OpenDialog();
			this.PostFirst();
		} //没有图片
		else
		{
			KE.insertHtml(this.EditorID, this.EditorContent);
			//this.UpdateContent();
		}
	};

	//粘贴Excel
	this.PasteExcel = function()
	{ 
		this.EditorContent = this.WordParser.GetExcel();
		//有图片
		if (this.WordParser.GetImages())
		{
			this.OpenDialog();
			this.PostFirst();
		} //没有图片
		else
		{
			KE.insertHtml(this.EditorID, this.EditorContent);
			//this.UpdateContent();
		}
	};

	//匹配形状
	this.MatchShape = function(data)
	{
		this.EditorContent = data;
		this.WordParser.Parse(this.EditorContent);
		//wps
		this.MatchImgs(this.EditorContent);
		this.MatchImgs2(this.EditorContent);
		this.OpenDialog();
		this.PostFirst();
	};

	//配置img标签
	//<img width="553" height="217" alt="" src="file:///C:/Users/ADMINI~1/AppData/Local/Temp/ksohtml/wps_clip_image-12942.png" />
	this.MatchImgs = function(html)
	{
		var imgStyle = /width=\"(\d+)\" height=\"(\d+)\" alt=\"\S*\" src=\"file:\/\/\/(\S+)\"/;
		var imgs = html.match(this.ImgRegx);
		if (null != imgs)
		{
			for (var i = 0, l = imgs.length; i < l; ++i)
			{
				var style = imgStyle.exec(imgs[i]);
				if (style)
				{
					this.AddFile(RegExp.$3, imgs[i], RegExp.$1, RegExp.$1);
				}
			}
		}
	};

	//WPS标签
	//<IMG src="file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ksohtml/wps_clip_image-25006.png" width=301 height=849>
	this.MatchImgs2 = function(html)
	{
		var imgStyle = /src=\"file:\/\/\/(\S+)\" width=(\d+) height=(\d+)/;
		var imgs = html.match(this.ImgRegx2);
		if (null != imgs)
		{
			for (var i = 0, l = imgs.length; i < l; ++i)
			{
				var style = imgStyle.exec(imgs[i]);
				if (style)
				{
					this.AddFile(RegExp.$1, imgs[i], RegExp.$2, RegExp.$3);
				}
			}
		}
	};

	/*
		解析形状项
		参数：
			shapeTag 匹配成功的HTML字符串
			shapeStyle 形状样式字符串。"WIDTH: 600pt; HEIGHT: 450pt" id=_x0000_i1025 alt="" type="#_x0000_t75"
			imageSrc 图片本地地址。
	*/
	this.MatchShapeItem = function(shapeTag, shapeStyle, imageSrc)
	{
		var width = 0;
		var height = 0;
		var style = this.ShapeStyleRegexs.wh.exec(shapeStyle);
		//匹配高度和宽度
		if (style)
		{
			width = Math.round(RegExp.$1 * 1.3333);
			height = Math.round(RegExp.$2 * 1.3333);
			height = isNaN(height) ? 0 : height;
		} //只匹配宽度，由控件自动计算比例
		else
		{
			style = this.ShapeStyleRegexs.w.exec(shapeStyle);
			if (style)
			{
				width = Math.round(RegExp.$1 * 1.3333);
			}
		}
		this.AddFile(imageSrc, shapeTag, width, height);
	};
	
	//只匹配图片
	this.MatchImage = function()
	{
		var urlReg = /(?:src=\"file:\/\/\/)(\S+)(?:\")/;
		var data = this.Editor.GetClipboardHTML();
		this.EditorContent = data; //保存到图片上传管理器中

		for (regName in this.ImgRegex)
		{
			var imgs = data.match(this.ImgRegex[regName]);
			if (null != imgs)
			{
				var len = imgs.length;
				var url = "";

				for (var i = 0; i < len; i++)
				{
					url = urlReg.exec(imgs[i]);
					if (url)
					{
						this.AddFile(RegExp.$1, imgs[i]);
					}
				}
			}
		}
		this.Dialog.show();
		this.PostFirst();
	};
	
	//开始上传编辑器中所有的WORD图片
	this.UploadImages = function()
	{
		var html = this.Editor.GetClipboardHTML();
		//测试代码。
		this.MatchShape(html);
	};
	//传送当前队列的第一个文件
	this.PostFirst = function()
	{
		if (this.UnUploaderIdList.length > 0)
		{
			var index = this.UnUploaderIdList.shift();
			this.UploaderList[index].Post();
		}
	};
	
	/*
	验证文件名是否存在
	参数:
		fileName:文件名称
	*/
	this.Exist = function(fileName)
	{
		for (var a in this.UploaderList)
		{
			if (this.UploaderList[a].LocalFile == fileName)
			{
				return true;
			}
		}
		return false;
	};

	/*
	根据ID删除上传任务
	参数:
	[0] FileID
	*/
	this.Delete = function()
	{
		var obj = this.UploaderList[arguments[0]];
		if (null == obj) return;

		var tbID = "item" + obj.FileID;
		var item = document.getElementById(tbID);
		if (item) document.removeChild(item); //删除
	};

	//根据上传信息层模板创建层对象
	this.CreateUploaderDiv = function()
	{
		return this.UploaderTemplateDiv.cloneNode(true);
	};

	/*
		添加到上传列表
		参数
			index 上传对象唯一标识
			uploaderObj 上传对象
	*/
	this.AppendToUploaderList = function(index, uploaderObj)
	{
		this.UploaderList[index] = uploaderObj;
		++this.UploaderListCount;
	};

	/*
		添加到上传列表层
		参数
			fid 文件ID
			div 上传信息层对象
			obj 上传对象
	*/
	this.AppendToListDiv = function(fid, div, obj)
	{
		var line = this.UploaderSplitLine.cloneNode(true); //分隔线
		line.id = "FilePostLine" + fid;
		line.style.display = "block";
		obj.Separator = line;

		this.UploaderListDiv.appendChild(div);
		this.UploaderListDiv.appendChild(line);
	};

	/*
		更新编辑器中的图片标签
		参数:
			0 原始图片标签
			1 新的图片地址
	*/
	this.ReplaceEditorImgTag = function(srcOld,srcNew)
	{
		var img = "<img src=\"";
		img += srcNew;
		img += "\" />";
		this.EditorContent = this.EditorContent.replace(srcOld, img);
		//this.Editor.SetData(this.EditorContent);
	};

	/*
		更新编辑器内容。
		在所有图片上传完后调用。
		在上传图片出现错误时调用。
	*/
	this.UpdateContent = function()
	{
		//var html = this.CleanWord(this.EditorContent, false, false);
		//this.Editor.SetData(html);
		KE.insertHtml(this.EditorID, this.EditorContent);
	};
	
	// This function will be called from the PasteFromWord dialog (fck_paste.html)
	// Input: oNode a DOM node that contains the raw paste from the clipboard
	// bIgnoreFont, bRemoveStyles booleans according to the values set in the dialog
	// Output: the cleaned string
	this.CleanWord = function(data, bIgnoreFont, bRemoveStyles)
	{
		var html = data;

		html = html.replace(/<o:p>\s*<\/o:p>/g, '');
		html = html.replace(/<o:p>[\s\S]*?<\/o:p>/g, '&nbsp;');

		// Remove mso-xxx styles.
		html = html.replace(/\s*mso-[^:]+:[^;"]+;?/gi, '');

		// Remove margin styles.
		html = html.replace(/\s*MARGIN: 0cm 0cm 0pt\s*;/gi, '');
		html = html.replace(/\s*MARGIN: 0cm 0cm 0pt\s*"/gi, "\"");

		html = html.replace(/\s*TEXT-INDENT: 0cm\s*;/gi, '');
		html = html.replace(/\s*TEXT-INDENT: 0cm\s*"/gi, "\"");

		html = html.replace(/\s*TEXT-ALIGN: [^\s;]+;?"/gi, "\"");

		html = html.replace(/\s*PAGE-BREAK-BEFORE: [^\s;]+;?"/gi, "\"");

		html = html.replace(/\s*FONT-VARIANT: [^\s;]+;?"/gi, "\"");

		html = html.replace(/\s*tab-stops:[^;"]*;?/gi, '');
		html = html.replace(/\s*tab-stops:[^"]*/gi, '');

		// Remove FONT face attributes.
		if (bIgnoreFont)
		{
			html = html.replace(/\s*face="[^"]*"/gi, '');
			html = html.replace(/\s*face=[^ >]*/gi, '');

			html = html.replace(/\s*FONT-FAMILY:[^;"]*;?/gi, '');
		}

		// Remove Class attributes
		html = html.replace(/<(\w[^>]*) class=([^ |>]*)([^>]*)/gi, "<$1$3");

		// Remove styles.
		if (bRemoveStyles)
			html = html.replace(/<(\w[^>]*) style="([^\"]*)"([^>]*)/gi, "<$1$3");

		// Remove style, meta and link tags
		html = html.replace(/<STYLE[^>]*>[\s\S]*?<\/STYLE[^>]*>/gi, '');
		html = html.replace(/<(?:META|LINK)[^>]*>\s*/gi, '');

		// Remove empty styles.
		html = html.replace(/\s*style="\s*"/gi, '');

		html = html.replace(/<SPAN\s*[^>]*>\s*&nbsp;\s*<\/SPAN>/gi, '&nbsp;');

		html = html.replace(/<SPAN\s*[^>]*><\/SPAN>/gi, '');

		// Remove Lang attributes
		html = html.replace(/<(\w[^>]*) lang=([^ |>]*)([^>]*)/gi, "<$1$3");

		html = html.replace(/<SPAN\s*>([\s\S]*?)<\/SPAN>/gi, '$1');

		html = html.replace(/<FONT\s*>([\s\S]*?)<\/FONT>/gi, '$1');

		// Remove XML elements and declarations
		html = html.replace(/<\\?\?xml[^>]*>/gi, '');

		// Remove w: tags with contents.
		html = html.replace(/<w:[^>]*>[\s\S]*?<\/w:[^>]*>/gi, '');

		// Remove Tags with XML namespace declarations: <o:p><\/o:p>
		html = html.replace(/<\/?\w+:[^>]*>/gi, '');

		// Remove comments [SF BUG-1481861].
		html = html.replace(/<\!--[\s\S]*?-->/g, '');

		html = html.replace(/<(U|I|STRIKE)>&nbsp;<\/\1>/g, '&nbsp;');

		html = html.replace(/<H\d>\s*<\/H\d>/gi, '');

		// Remove "display:none" tags.fix bug:可能会替换img标签
		//html = html.replace(/<(\w+)[^>]*\sstyle="[^"]*DISPLAY\s?:\s?none[\s\S]*?<\/\1>/ig, '');

		// Remove language tags
		html = html.replace(/<(\w[^>]*) language=([^ |>]*)([^>]*)/gi, "<$1$3");

		// Remove onmouseover and onmouseout events (from MS Word comments effect)
		html = html.replace(/<(\w[^>]*) onmouseover="([^\"]*)"([^>]*)/gi, "<$1$3");
		html = html.replace(/<(\w[^>]*) onmouseout="([^\"]*)"([^>]*)/gi, "<$1$3");

		if (false)
		{
			// The original <Hn> tag send from Word is something like this: <Hn style="margin-top:0px;margin-bottom:0px">
			html = html.replace(/<H(\d)([^>]*)>/gi, '<h$1>');

			// Word likes to insert extra <font> tags, when using MSIE. (Wierd).
			html = html.replace(/<(H\d)><FONT[^>]*>([\s\S]*?)<\/FONT><\/\1>/gi, '<$1>$2<\/$1>');
			html = html.replace(/<(H\d)><EM>([\s\S]*?)<\/EM><\/\1>/gi, '<$1>$2<\/$1>');
		}
		else
		{
			html = html.replace(/<H1([^>]*)>/gi, '<div$1><b><font size="6">');
			html = html.replace(/<H2([^>]*)>/gi, '<div$1><b><font size="5">');
			html = html.replace(/<H3([^>]*)>/gi, '<div$1><b><font size="4">');
			html = html.replace(/<H4([^>]*)>/gi, '<div$1><b><font size="3">');
			html = html.replace(/<H5([^>]*)>/gi, '<div$1><b><font size="2">');
			html = html.replace(/<H6([^>]*)>/gi, '<div$1><b><font size="1">');

			html = html.replace(/<\/H\d>/gi, '<\/font><\/b><\/div>');

			// Transform <P> to <DIV>
			var re = new RegExp('(<P)([^>]*>[\\s\\S]*?)(<\/P>)', 'gi'); // Different because of a IE 5.0 error
			html = html.replace(re, '<div$2<\/div>');

			// Remove empty tags (three times, just to be sure).
			// This also removes any empty anchor
			html = html.replace(/<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '');
			html = html.replace(/<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '');
			html = html.replace(/<([^\s>]+)(\s[^>]*)?>\s*<\/\1>/g, '');
		}
		//<span style="font-family: 宋体; font-size: 12pt"><img alt="" src="/upload/2011-12-03_1119250937.jpg" /></span>
		html = html.replace(/<span[^>]*>(<img.+\/>)<\/span>/gi, '$1');
		//<div style="margin-top: 0pt; margin-bottom: 0pt"><img alt="" src="/upload/2012-01-08_2246370625.jpg" /></div>
		html = html.replace(/<div[^>]*>(<img.+\/>)<\/div>/gi, '$1<br/>');
		//<a name="OLE_LINK2"><span><img/><img/></a>
		html = html.replace(/<a[^>]*>((<span>)?(<img.+\/>).*)<\/a>/gi, '$3');
		return html;
	};
}

/*
	添加图片
	参数：
		obj
		alt
		width
		height
		src
		img
*/
function WordParser_AddImage(obj,alt,width,height,src,img)
{ 
	obj.AddFile(src, img, width, height);
}

/*
	添加一个文件到上传队列
	参数:
		[0] 文件名称
		[1] imgTag图片标记
		width 图片宽度
		heigth 图片高度
	返回值:
	文件上传对象
*/
WordPasterManager.prototype.AddFile = function(imgPath,imgHtml,width,height)
{
	//本地文件名称不存在
	//if (!this.Exist(arguments[0]))
	{
		var fileNameArray = imgPath.split("\\");
		var fileName = fileNameArray[fileNameArray.length - 1];
		var fid = this.UploaderListCount;
		this.UnUploaderIdList.push(fid); //添加到未上传列表
		
		var upFile = new FileUploader(fid, imgPath, this,width,height);
		var newTable = this.CreateUploaderDiv();
		newTable.style.display = "block";
		newTable.id = "item" + fid;
		var divLeft = newTable.children(0);
		var divRight = newTable.children(1);
		var objFileName = divLeft.children(0);
		objFileName.innerText = fileName;
		objFileName.title = arguments[0];
		upFile.pProcess = divLeft.children(1).children(0);
		upFile.pMsg = divLeft.children(2);
		upFile.pMsg.innerText = "";
		upFile.pButton = divRight.children(0);
		upFile.pButton.fid = fid;
		upFile.pButton.domid = "item" + fid;
		upFile.pButton.lineid = "FilePostLine" + fid;
		upFile.pButton.attachEvent("onclick", BtnControlClick);
		upFile.pPercent = divRight.children(1);
		upFile.pPercent.innerText = "0%";
		upFile.ImageTag = imgHtml; //图片标记
		upFile.Manager = this;
		upFile.InfDiv = newTable;//上传信息DIV

		//添加到上传列表层
		this.AppendToListDiv(fid, newTable,upFile);

		//添加到上传列表
		this.AppendToUploaderList(fid, upFile);
		//this.UpFileList.appendChild(newTable);
		//this.UpFileList.appendChild(line);
		//upFile.Post(); //开始上传
		upFile.Ready(); //准备
	}
}

/*
	添加本地文件
	参数:
		imgPath	本地图片文件路径
	返回值:
		文件上传对象
*/
WordPasterManager.prototype.AddLocalFile = function(imgPath)
{
	//本地文件名称不存在
	//if (!this.Exist(arguments[0]))
	{
		var fileNameArray = imgPath.split("\\");
		var fileName = fileNameArray[fileNameArray.length - 1];
		var fid = this.UploaderListCount;
		this.UnUploaderIdList.push(fid); //添加到未上传列表

		var upFile = new FileUploader(fid, imgPath, this, 0, 0);
		upFile.ATL.ImageType = fileName.split(".")[1];
		upFile.PostLocalFile = true;
		var newTable = this.CreateUploaderDiv();
		newTable.style.display = "block";
		newTable.id = "item" + fid;
		var divLeft = newTable.children(0);
		var divRight = newTable.children(1);
		var objFileName = divLeft.children(0);
		objFileName.innerText = fileName;
		objFileName.title = arguments[0];
		upFile.pProcess = divLeft.children(1).children(0);
		upFile.pMsg = divLeft.children(2);
		upFile.pMsg.innerText = "";
		upFile.pButton = divRight.children(0);
		upFile.pButton.fid = fid;
		upFile.pButton.domid = "item" + fid;
		upFile.pButton.lineid = "FilePostLine" + fid;
		upFile.pButton.attachEvent("onclick", BtnControlClick);
		upFile.pPercent = divRight.children(1);
		upFile.pPercent.innerText = "0%";
		upFile.ImageTag = ""; //图片标记
		upFile.Manager = this;
		upFile.InfDiv = newTable; //上传信息DIV

		//添加到上传列表层
		this.AppendToListDiv(fid, newTable, upFile);

		//添加到上传列表
		this.AppendToUploaderList(fid, upFile);
		//this.UpFileList.appendChild(newTable);
		//this.UpFileList.appendChild(line);
		//upFile.Post(); //开始上传
		upFile.Ready(); //准备
	}
}

/*
	单击控制按钮
	参数:
		[0]
*/
function BtnControlClick() 
{
	var obj = event.srcElement;//<a fid=""></a>
	var objup = WordPasterManagerInstance.UploaderList[obj.fid];

	switch (obj.innerText) 
	{
		case "暂停":
		case "停止":
			objup.Stop(obj.fid);
			break;
		case "取消":
			{
				var lister = WordPasterManagerInstance.UploaderListDiv;
				var item = document.getElementById(obj.domid);
				var line = document.getElementById(obj.lineid);
				if (item) lister.removeChild(item);
				if (line) lister.removeChild(line);
			}
			break;
		case "续传":
		case "重试":
			objup.Post();
			break;
	}
}

var FileUploaderState = {
	Ready: 0,
	Posting: 1,
	Stop: 2,
	Error: 3,
	GetNewID: 4,
	Complete: 5,
	WaitContinueUpload: 6,
	None: 7,
	Waiting: 8
};

/*
	文件上传对象
	参数：
		fileID 文件唯一标识
		filePath 包含完整路径的本地文件名称。D:\Soft\QQ.exe
		width 图片宽度
		height 图片高度
	属性：
		pMsg		显示上传信息，进度信息
		pProcess	进度条
		pPercent	显示百分比文字
		pButton		按钮按钮
		LocalFile	本地文件路径。D:\Soft\QQ.exe
		ImageTag	图片标记。
		InfDiv		上传信息层。
		Separator	分隔线
*/
function FileUploader(fileID,filePath,mgr,width,height)
{
	this.EditorID = mgr.EditorID;
	this.Manager = mgr;
	this.Config = mgr.Config;
	this.ActiveX = mgr.ActiveX;
	this.Fields = mgr.Fields;
	this.PostLocalFile = false; //是否上传本地文件

	this.ATL = new ActiveXObject(this.ActiveX["Uploader"]);
	this.ATL.PostUrl = this.Config["PostUrl"];
	this.ATL.EncodeType = this.Config["EncodeType"];
	this.ATL.ImageType = this.Config["PasteWordType"];
	this.ATL.SetThumbSize(this.Config["ThumbWidth"], this.Config["ThumbHeight"]);
	
	//添加附加字段
	var pname;
	for (pname in this.Fields)
	{
		this.ATL.AddField(pname, this.Fields[pname]);
	}
	this.ATL.OnComplete = HttpUploader_Complete;
	this.ATL.OnPost = HttpUploader_Process;
	this.ATL.OnError = HttpUploader_Error;
	this.ATL.OnConnected = HttpUploader_Connected;
	this.ATL.Object = this;
	this.ATL.LocalFile = filePath;
	this.ATL.CompanyLicensed = this.Config["Licensed"];
	this.ATL.FileID = fileID;
	this.ATL.Width = width;
	this.ATL.Height = height;

	this.State = FileUploaderState.None;
	this.LocalFile = filePath;
	this.FileID = fileID;
	this.ImageTag = ""; //图片标记，在图片上传完后需要替换此标记

	//方法-准备
	this.Ready = function()
	{
		//this.pButton.style.display = "none";
		this.pMsg.innerText = "正在上传队列中等待...";
		this.State = FileUploaderState.Ready;
	};

	//方法-开始传输
	this.Post = function()
	{
		//存在相同图片项
		if (this.ExistSameImage()) return;
		
		this.pButton.style.display = "";
		this.pButton.innerText = "停止";
		this.State = FileUploaderState.Posting;
		this.ATL.Post();
	};

	//存在相同项，本地图片地址相同
	this.ExistSameImage = function()
	{
		//已上传列表中存在相同项
		if (this.Manager.CompleteExist(this.LocalFile))
		{
			var url = this.Manager.CompleteGet(this.LocalFile);
			this.pButton.innerText = "";
			this.pProcess.style.width = "100%";
			this.pPercent.innerText = "100%";
			this.pMsg.innerText = "上传完成";
			this.State = FileUploaderState.Complete;

			//从上传列表中清除
			this.Remove();
			//更新编辑器中的图片标签
			this.ReplaceEditorImgTag(url);
			this.PostNext();
			return true;
		}
		return false;
	};

	//从上传列表中删除
	this.Remove = function()
	{
		//删除信息层
		this.Manager.UploaderListDiv.removeChild(this.InfDiv);
		//删除分隔线
		this.Manager.UploaderListDiv.removeChild(this.Separator);
		//清空本地文件名称
		this.LocalFile = "";
	};

	//方法-启动下一个传输
	this.PostNext = function()
	{
		if (this.Manager.UnUploaderIdList.length > 0)
		{
			var index = this.Manager.UnUploaderIdList.shift();
			var obj = this.Manager.UploaderList[index];

			//空闲状态
			if (FileUploaderState.Ready == obj.State)
			{
				obj.Post();
			}
		} //所有文件上传完毕
		else
		{
			//上传Word图片时才替换内容
			if (!this.PostLocalFile)
			{
				this.Manager.UpdateContent();
			}
			this.Manager.CloseDialog();
		}
	};
	
	//停止传输
	this.Stop = function(fid)
	{
		var obj = this.Manager.UploaderList[fid];
		obj.ATL.Stop();
		obj.State = FileUploaderState.Stop;
		obj.pButton.innerText = "续传";
	};

	//替换编辑器中的图片标签
	this.ReplaceEditorImgTag = function(imgSrc)
	{
		this.Manager.ReplaceEditorImgTag(this.ImageTag, imgSrc);
	};

	//本地图片文件上传完毕
	this.LocalFileComplete = function(imgSrc)
	{
		var img = '<img src="' + imgSrc + '"/>';
		KE.insertHtml(this.EditorID, img);
	};

	//文件上传完毕
	this.FilePostComplete = function(imgSrc)
	{
		//上传的本地文件
		if (this.PostLocalFile)
		{
			this.LocalFileComplete(imgSrc);
		} //上传的Word中的图片
		else
		{
			this.ReplaceEditorImgTag(imgSrc);
		}
	};
}

//连接成功
function HttpUploader_Connected(obj)
{
	obj.pMsg.innerText = "服务器连接成功";
}

//传输完毕
function HttpUploader_Complete(obj)
{
	obj.pButton.innerText = "";
	obj.pProcess.style.width = "100%";
	obj.pPercent.innerText = "100%";
	obj.pMsg.innerText = "上传完成";
	obj.State = FileUploaderState.Complete;

	//添加到已上传列表
	obj.Manager.CompleteAdd(obj.LocalFile, obj.ATL.Response);
	//从上传列表中清除
	obj.Remove();
	//更新编辑器中的图片标签
	obj.FilePostComplete(obj.ATL.Response);
	obj.PostNext();
}

//传输进度
function HttpUploader_Process(obj, speed, postedLen, percent, time)
{
	obj.pPercent.innerText = percent;
	obj.pProcess.style.width = percent;
	obj.pMsg.innerText = "已上传:" + postedLen;
	obj.pMsg.innerText += " 速度:" + speed;
	obj.pMsg.innerText += " 剩余时间:" + time;
}

//伟输错误
function HttpUploader_Error(obj, err)
{
	obj.pMsg.innerText = WordPasterError[err];
	obj.pButton.innerText = "重试";
	obj.State = FileUploaderState.Error;
	obj.PostNext(); //继续传输下一个
}

var ImagePasterState = {
	Posting: 0
	, Stop: 1
	, Error: 2
	, Complete: 3
	, None: 4
};

/*
	图片粘贴器。负责从剪帖板中获取图片数据，并自动上传到WEB服务器中。
	参数:
	[0] 显示粘贴信息的层
	属性
	InfoDiv 提示信息层，用来显示图片粘贴器的处理进度信息。
	关联HTML元素：
		粘贴信息层：PasterMessager
*/
function ImagePasterManager(mgr)
{
	this.Manager = mgr;
	this.Config = mgr.Config;
	this.Fields = mgr.Fields;
	this.ActiveX = mgr.ActiveX;
	//图片粘贴窗口
	this.OpenDialog = mgr.OpenPasteFileDialog;
	this.CloseDialog = mgr.ClosePasteFileDialog;
	
	this.InfoDiv = document.getElementById("PasterMessager"); //提示信息层
	this.InfoIco = document.getElementById("infIco"); //信息图标
	this.Message = this.InfoDiv.children(1);
	this.Progress = this.InfoDiv.children(2);
	this.State = ImagePasterState.None;
	this.Editor = null;

	//初始化，在页面加载完后调用
	this.Init = function()
	{
		this.Com = new ActiveXObject(this.ActiveX["ImagePaster"]);
		this.Com.Object = this;
		this.Com.ImageType = this.Config["PasteImageType"];
		this.Com.PostUrl = this.Config["PostUrl"];
		this.Com.Licensed = this.Config["Licensed"];
		this.Com.EncodeType = this.Config["EncodeType"];
		this.Com.SetThumbSize(this.Config["ThumbWidth"], this.Config["ThumbHeight"]);
		//this.Com.WebDocument = document;//必须放在后面设置
		//连接事件
		this.Com.OnConnected = ImagePaster_Connected;
		this.Com.OnComplete = ImagePaster_Complete;
		this.Com.OnPost = ImagePaster_OnProcess;
		this.Com.OnError = ImagePaster_OnError;
	};

	this.IsBitmap = function()
	{
		return this.Com.IsBitmap();
	};

	this.IsFile = function()
	{
		return this.Com.IsFile();
	};
	
	//是否正在上传
	this.IsPosting = function()
	{
		return this.State == ImagePasterState.Posting;
	};

	//粘贴
	this.Paste = function()
	{
		//清空附加字段
		this.Com.ClearFields();
		var item = null, fields = this.Fields;
		for (item in fields)
		{
			this.Com.AddField(item, fields[item]);
		}

		this.Com.Paste();
		this.OpenDialog();//显示图片上传窗口
	};

	//粘贴多张图片
	this.PasteFiles = function()
	{
		this.Manager.OpenUploadFileDialog();
		var files = this.Com.GetFiles();
		for (var i = files.lbound(1); i <= files.ubound(1); i++)
		{
			this.Manager.WordPaster.AddLocalFile(files.getItem(i));
			this.Manager.WordPaster.PostFirst();
		}
	};
}

//服务器连接成功
function ImagePaster_Connected(obj)
{
	obj.InfoDiv.style.display = "block";
	obj.Progress.innerText = "10%";
	obj.State = ImagePasterState.Posting;
}

//图片上传完毕
function ImagePaster_Complete(obj)
{
	obj.Progress.innerText = "100%";
	obj.Message.innerText = "上传完成";
	obj.State = ImagePasterState.Complete;
	obj.CloseDialog(); //显示图片上传窗口

	//插入到编辑器
	var img = "<img src=\"";
	img += obj.Com.Response;
	img += "\" />";
	// Insert as plain text.
	KE.insertHtml(obj.EditorID,img);
}

/*
事件-传输中....
参数:
obj JS对象
speed	传输速度
length 已传输长度。1Byte,1KB,1MB,1GB
percent 上传百分比
time 剩余时间
*/
function ImagePaster_OnProcess(obj, speed, length, percent, time)
{
	obj.Progress.innerText = percent;
}

//事件-传输停止。暂时未使用
function ImagePaster_Stop(obj)
{
	obj.Com.Stop();
	obj.State = ImagePasterState.Stop;
}
/*
事件-传输错误
参数:
obj JS对象
err 错误码
*/
function ImagePaster_OnError(obj, ert)
{
	obj.Message.innerText = WordPasterError[ert];
	obj.InfoIco.src = obj.Config["IcoPath"] + "error.png";
	obj.Progress.innerText = "";
	obj.State = ImagePasterState.Error;
}

//粘贴管理器
function PasterManager()
{
	this.Fields = {}; //符加信息
	this.UploadDialogCreated = false;
	this.PasteDialogCreated = false;
	//配置信息
	this.Config = {
		"EncodeType"		: "GB2312"
		, "Licensed"		: "武汉命运科技有限公司"
		, "PasteWordType"	: "JPG"	//粘贴WORD的图片格式。JPG/PNG/GIF/BMP,推荐使用JPG，防止BMP图片太大。
		, "PasteImageType"	: ""	//粘贴文件，剪帖板的图片格式，为空表示本地图片格式。JPG/PNG/GIF/BMP
		, "JpgQuality"		: 80	//JPG质量。0~100
		, "ThumbWidth"		: 0		//缩略图宽度。0表示不使用缩略图
		, "ThumbHeight"		: 0		//缩略图高度。0表示不使用缩略图
		, "ClsidImagePaster": "DC4A6931-3570-44b4-842D-C13EE637BBC1"
		, "ClsidUploader"	: "26CFEDE7-789D-4077-B49D-C7F1D7150B93"
		, "ClsidParser"		: "1832A49E-09D5-470E-AA4B-BE8F28034218"
		, "CabPath"			: "http://www.ncmem.com/products/word-imagepaster/kindeditor351/WordPaster/WordPaster.cab#version=1,4,42,55270"
		, "IcoPath"			: "http://www.ncmem.com/products/word-imagepaster/fckeditor2461/WordPaster/"
		, "PostUrl"			: "http://www.ncmem.com/products/word-imagepaster/fckeditor2461/asp.net/upload.aspx"
	};

	this.ActiveX = {
		"Uploader"		: "Xproer.ImageFileUploader"
		, "ImagePaster"	: "Xproer.ImagePaster"	//
		, "WordParser"	: "Xproer.WordParser"
	};
	
	//加载控件及HTML元素
	this.Load = function()
	{
		//Word图片粘贴
		var acx = '<div style="display: none;">';
		acx += ' <object id="Paster" classid="clsid:' + this.Config["ClsidImagePaster"] + '"';
		acx += ' codebase="' + this.Config["CabPath"] + '"';
		acx += ' width="1" height="1" ></object>';
		//Word图片上传控件
		acx += ' <object id="Uploader" classid="clsid:' + this.Config["ClsidUploader"] + '"';
		acx += ' codebase="' + this.Config["CabPath"] + '"';
		acx += ' width="1" height="1" ></object>';
		//Word解析组件
		acx += ' <object id="objWordParser" classid="clsid:' + this.Config["ClsidParser"] + '"';
		acx += ' codebase="' + this.Config["CabPath"] + '"';
		acx += ' width="1" height="1" ></object>';
		/*
			静态加截控件代码，在复杂WEB系统中或者框架页面中请静态方式加截Word解析组件(Xproer.WordParser)。
			<object id="objWordParser" classid="clsid:1832A49E-09D5-470E-AA4B-BE8F28034218"	width="1" height="1" ></object>
		*/
		//
		acx += '<div id="PasterMessager">';
		acx += '<img id="infIco" alt="进度图标" src="' + this.Config["IcoPath"] + '/upload.gif" /><span>图片上传中...</span><span>10%</span>';
		acx += '</div>';

		//文件上传列表项模板
		acx += '<div class="UploaderItem" id="UploaderTemplate">';
		acx += '<div class="UploaderItemLeft">';
		acx += '<div class="FileName top-space">HttpUploader程序开发.pdf</div>';
		acx += '<div class="ProcessBorder top-space">';
		acx += '<div class="Process"></div>';
		acx += '</div>';
		acx += '<div class="PostInf top-space">已上传:15.3MB 速度:20KB/S 剩余时间:10:02:00</div>';
		acx += '</div>';
		//right
		acx += '<div class="UploaderItemRight">';
		acx += '<a class="Btn" href="javascript:void(0)">取消</a>';
		acx += '<div class="ProcessNum">35%</div>';
		acx += '</div>';
		acx += '</div>'//template end
		//分隔线
		acx += '<div class="Line" id="FilePostLine"></div>';
		//上传列表
		acx += '<div id="ImageUploadDialog" title="上传图片">';
		acx += '<div id="FilePostLister"></div>';
		acx += '</div>';
		//hide div end
		acx += '</div>';
		
		document.write(acx);
	};

	//打开图片上传对话框
	this.OpenUploadFileDialog = function()
	{
		if (!this.UploadDialogCreated)
		{
			// 定义图片上传对话框
			$('#ImageUploadDialog').dialog({
				autoOpen: false,
				resizable: false,
				width: 480,
				buttons: {
					"退出": function()
					{
						$(this).dialog("close");
					}
				}
			});
			this.UploadDialogCreated = true;
		}

		$('#ImageUploadDialog').dialog('open');
	};
	this.CloseUploadFileDialog = function()
	{
		$('#ImageUploadDialog').dialog('close');
		this.CompleteClear(); //清空图片缓存
	};
	//打开粘贴图片对话框
	this.OpenPasteFileDialog = function()
	{
		if (!this.PasteDialogCreated)
		{
			//图片粘贴上传对话框
			$('#PasterMessager').dialog({
				autoOpen: false,
				resizable: false,
				width: 300,
				height: 200
			});
			this.PasteDialogCreated = true;
		}
		$('#PasterMessager').dialog('open');
	};
	this.ClosePasteFileDialog = function()
	{
		$('#PasterMessager').dialog('close');
	};

	//一般在KindEditor加载完毕后调用
	this.Init = function(kid)
	{
		this.WordParser = document.getElementById("objWordParser");
		this.WordPaster = new WordPasterManager(this);
		this.ImagePaster = new ImagePasterManager(this);
		
		this.ImagePaster.Init();
		this.SetEditorID(kid);
		this.LoadPasteEvent(kid);

		this.WordRange = document.body.createTextRange();
		this.WordDiv = document.getElementById("divWord");
	};

	//在Init()函数中调用
	this.SetEditorID = function(id)
	{
		this.EditorID = id;
		this.ImagePaster.EditorID = id;
		this.WordPaster.EditorID = id;
	};

	//挂载粘贴事件
	this.LoadPasteEvent = function(id)
	{
		var mgr = this;
		KE.event.add(KE.g[id].iframeDoc.body, 'paste', function(e)
		{
			return mgr.Paste();
		});
	};
	
	//单击按钮粘贴
	this.Paste = function()
	{
		//是图片文件
		if (this.ImagePaster.IsBitmap())
		{
			if (!this.ImagePaster.IsPosting())
			{
				this.ImagePaster.Paste();
			}
		} //上传本地硬盘文件图片
		else if (this.ImagePaster.IsFile())
		{
			this.ImagePaster.PasteFiles();
		} //上传WORD图片
		else if (this.WordParser.IsWord())
		{
			this.WordPaster.PasteWord();
		} //文本
		else
		{
			return true;
		}
		return false;
	};
	
	//粘贴Excel
	this.PasteExcel = function()
	{
		if (this.WordParser.IsWord())
		{
			this.WordPaster.PasteExcel();
		}
	};
}